import 'dart:async';
import 'dart:ui';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:dio/dio.dart';
import 'package:flutter_chat_ui/https/http_exception.dart';
import 'package:flutter_chat_ui/https/http_response.dart';
import 'package:flutter_chat_ui/https/url.dart';
import 'package:logger/web.dart';

/// 连接超时时间
const int _connectTimeout = 60000;

/// 发送超时时间
const int _sendTimeout = 60000;

/// 成功回调
typedef Success<T> = void Function(T data);

/// 失败回调
typedef Fail = Function(int code, String msg);

class XHttpRequest {
  static Dio? _dio;

  static Dio get dio => createInstance();

  /// 创建 dio 实例对象
  static Dio createInstance({int receiveTimeout = 60000}) {
    if (_dio == null) {
      var options = BaseOptions(
        contentType: Headers.jsonContentType,
        validateStatus: (status) => true,
        sendTimeout: const Duration(milliseconds: _sendTimeout),
        connectTimeout: const Duration(milliseconds: _connectTimeout),
        receiveTimeout: Duration(milliseconds: receiveTimeout),
        baseUrl: XHttpUrl.baseUrl,
      );
      _dio = Dio(options);
    }
    return _dio!;
  }

  /// 请求，返回参数为 T
  static Future<dynamic> request(
    Method method,
    String path, {
    dynamic params,
    Map<String, String>? header,
    Success<dynamic>? success,
    Fail? fail,
    VoidCallback? complete,
    CancelToken? cancelToken,
    ProgressCallback? onSendProgress,
    bool isStream = false,
  }) async {
    try {
      var connectivityResult = await (Connectivity().checkConnectivity());

      if (connectivityResult.contains(ConnectivityResult.none)) {
        fail?.call(XHttpException.netError, XHttpException.netWorkError);
        return Future.value(null);
      }

      Dio dio = createInstance();
      Logger().d("请求参数：uri：$path，param：$params");

      Response response = await dio.request(
        path,
        data: params,
        cancelToken: cancelToken,
        onSendProgress: onSendProgress,
        options: Options(
          method: MethodValues[method],
          headers: await _headerOptions(header, url: path),
          responseType: isStream ? ResponseType.stream : ResponseType.json,
        ),
      );

      // 流式
      if (isStream) {
        if (Result.isSuccess(response.statusCode ?? -1)) {
          final body = response.data as ResponseBody;
          success?.call(body.stream);
        } else {
          fail?.call(response.statusCode ?? -1, response.statusMessage ?? "未知错误");
        }
        return Future.value(response.data.stream);
      } else {
        var result = Result.fromJson(response);
        if (Result.isSuccess(response.statusCode ?? -1)) {
          success?.call(result.data);
        } else {
          Logger().e("result fail -> code: ${result.statusCode} msg:${result.statusMessage}");
          fail?.call(result.statusCode ?? -1, result.statusMessage ?? "未知错误");
        }
        return Future.value(result.data);
      }
    } on DioException catch (e) {
      final NetError netError = XHttpException.handleException(e);
      fail?.call(netError.code, netError.errorMsg);

      Logger().e("error =====> message: ${e.message},\ntype:${e.type},\nresponse:${e.response}, \nerror:${e.error}");
      return Future.value(null);
    } finally {
      complete?.call();
    }
  }
}

///
/// 处理请求头
///
Future<Map<String, dynamic>?> _headerOptions(Map<String, String>? optionalHeader, {String? url}) async {
  Map<String, String> defaultHeaders = {
    'Authorization': "Bearer app-reZTkYo7elrW2ioW39dgsF7f",
    'Content-Type': 'application/json',
  };

  if (optionalHeader != null) {
    defaultHeaders.addAll(optionalHeader);
  }
  Logger().d("请求头信息：uri：$url，request_header：${defaultHeaders.toString()}");
  return defaultHeaders;
}
